\section{Aspetti implementativi}\label{aspettiImplementativi}
Questa sezione espone, in maniera dettagliata, le scelte implementative dei punti soggetti a guasti che influiscono sulla corretta computazione del sistema.
\subsection{Introduzione all'architettura software}
Come anticipato nella sezione \ref{introduzione}, allo scopo di ridurre al minimo i costi di comunicazione e coordinamento tra i processi in gioco, abbiamo complicato la logica applicativa, ottenendo un livello di accopiamento relativamente alto tra i componenti che gestiscono il livello di comunicazione e le componenti che gestiscono la logica di gioco. Questo infatti, allo stato attuale delle cose, non ci consente di tracciare un confine ben definito tra le parti software in questione. Le due immagini seguenti, \ref{fig:DiagrammaClassirete} e \ref{fig:DiagrammaClassigrafica}, mostrano le connessioni principali fra le classi e i relativi ruoli nel software. 
\begin{figure}[h]
\centering
\caption{Diagramma delle classi di comunicazione}
\label{fig:DiagrammaClassirete}
\includegraphics[width=12cm]{img/classirete.png}
\end{figure}
\\\\ Come si pu\`o notare dal diagramma, le classi relative alla rete mantengono un eccessivo livello di accoppiamento con la parte di modello. Tale accoppiamento rende pi\`u complessa la manutenzione e l'introduzione di nuove funzionalit\`a.
\begin{figure}[h]
%\centering
\caption{Diagramma delle classi relativo all'interfaccia utente}
\label{fig:DiagrammaClassigrafica}
\includegraphics[width=12cm]{img/classigrafica.png}
\end{figure}
\\In contrasto la parte grafica non soffre dei problemi precedenti grazie ad un'applicazione pi\`u accurata dei principi del design pattern.
\subsection{Distribuzione delle carte}
La distribuzione delle carte viene affidata al primo leader. Tale leader viene calcolato seguendo una logica di iscrizione. Nel momento in cui il primo iscritto riceve la lista dei giocatori, si accorge di essere leader e quindi fornisce ad ogni giocatore nella lista, compreso se stesso, il mazzo e la mano. Tale consegna avviene mediante messaggi diretti. \\ Una volta finita tale consegna, per tollelare il guasto del leader, il leader invia un token nell'anello, in senso anti-gioco in modo tale da garantire che il leader successivo riceva il token per ultimo. Non appena un peer riceve il token abilita la visualizzazione delle carte e inoltra il token al successivo. Una volta che il token torna al mittente il gioco ha inizio. Le carte possono essere visualizzate all'arrivo del token perch\`e questo garantisce che tutti i giocatori hanno ricevuto il medesimo stato di gioco e quindi il sistema \`e consistente. La morte di un peer ``non leader'' (vedi immagine \ref{fig:Diagrammadistcarte}) non crea problemi se non in casi particolari che potrebbero richiedere il ri-invio del token da parte del leader. Mentre la morte del leader pu\`o avvenire in tre casi: 
\begin{enumerate}
\item Non sono state distribuite carte o sono state distribuite ad una frazione del sistema
\item Sono state distribuite le carte a tutto il sistema ma il token non \`e mai stato inviato
\item Sono state distribuite le carte e il token \`e stato inviato.
\end{enumerate}
Il secondo e il terzo caso si risolvono in maniera analoga con l'invio da parte del leader successivo di un nuovo token. Lo stato del sistema rimane inalterato.\\ Nel primo caso invece il futuro leader sa che il sistema potrebbe essere in uno stato inconsistente quindi riallinea lo stato iniziando una nuova procedura di consegna delle carte.
\`E importante notare che l'invio del token in senso anti-gioco garantisce che nel momento in cui il leader riceve un qualsiasi messaggio allora tutto il sistema ha gi\`a ricevuto quel messaggio.

\begin{figure}[h]
\centering
\caption{Diagramma di distribuzione delle carte}
\label{fig:Diagrammadistcarte}
\includegraphics[width=12cm, height=9cm]{img/distcarte.png}
\end{figure}

\subsection{Protocollo di aggiornamento}
Nella sezione \ref{aspettiProgettuali} è stato accennato come il modello architetturale utilizzato e le modalità con cui vengono effettuate le propagazioni degli aggiornamenti di stato, influiscono sulla gestione dei guasti durante le invocazioni remote che il processo leader effettua a tempo di gioco. Ci basti solo pensare che la propagazione dell'aggiornamento di stato in direzione anti-gioco si sostituisce naturalmente ad una logica di gestione post-aggiornamento, nella quale i processi in gioco si accordano tra loro sull'effettiva avvenuta ricezione del nuovo stato. Infatti, una volta ricevuto il token e aggiornato lo stato locale di gioco, il nuovo processo leader può essere abilitato a continuare la partita senza effettuare controlli di sorta, basandosi su una semplice assunzione di causalità logica; ovvero, se il token ha raggiunto l'\emph{n-esimo} peer, allora ha raggiunto anche il peer $n-1$, $n-2$, ..., $2$.
\\\'E importante per il candidato leader che tale garanzia sia preservata anche in presenza di guasti.
Questo può essere possibile solamente se, durante il percorso del token attraverso l'anello, ogni guasto di tipo crash viene rilevato ed autogestito dai peer intermedi, compresi tra il leader ed il candidato leader.
\\\\Durante l'analisi progettuale, sono state modellate due differenti tipologie di guasto, contestuali alla fase di aggiornamento e propagazione del nuovo stato di gioco: \emph{guasto del peer generico} (\ref{guastopeergenerico}), \emph{guasto del leader} (\ref{guastoleader}).
\\Il guasto del peer generico si suddivide in ulteriori due sottocategorie: \emph{guasto pre-ricezione}, \emph{guasto post-ricezione}.
%\\\\
\subsubsection{Guasto del peer generico}\label{guastopeergenerico}
\underline{\textbf{Guasto pre-ricezione}}\\
La prima tipologia di guasto, pre-ricezione, si ha in uno scenario canonico nel quale, l'{i-esimo} peer, invocando il metodo di propagazione dello stato, \texttt{propagateStatus()}, della classe \texttt{UnoPlayer}, riscontra che l'host remoto $i+1$, non è raggiungibile.
\\Tale situazione viene banalmente gestita catturando l'eccezione \texttt{RemoteException} lanciata dal metodo remoto \texttt{UpdateGameStatus()}, dichiarato nell'interfaccia remota. Contestualmente alla cattura di tale eccezione, il peer che ha avuto un guasto, $i+1$, viene rimosso dalla lista ordinata dei giocatori tenuta dall'\emph{i-esimo}, il quale, conseguentemente, provvederà a ri-propagare il token al peer immediatamente dopo.(vedi immagine \ref{fig:Diagrammaguastopeer}) Da qui si intuisce banalmente che tale schema risolutivo può essere applicato ricorsivamente su tutti gli $n-i$ guasti possibili.
\begin{figure}[h]
\centering
\caption{Guasto pre-ricezione di un peer generico}
\label{fig:Diagrammaguastopeer}
\includegraphics[width=10cm]{img/guastopeer2.png}
\end{figure} \\\\\\
\underline{\textbf{Guasto post-ricezione}}\\
Il guasto \emph{post-ricezione}, si identifica nello scenario in cui un peer intermedio riceve il token, ma prima di effettuare la progazione al successivo ha un guasto.
\\Tale scenario è estremamente poco frequente ma è verificabile tramite la realizzazione ad-hoc di un client guasto.
\\Tipicamente però, grazie alle proprietà delle invocazione RMI sincrone, sarebbe possibile ricondurre la modalità di gestione di questo scenario, allo schema risolutivo proposto per il fallimento pre-ricezione.
Infatti la ricezione del token, l'aggiornamento dello stato locale e la propagazione al successivo peer, risiedono nell'implementazione dello stesso metodo remoto, \texttt{UpdateGameStatus()}. RMI solleva una \texttt{RemoteException} ogni qualvolta il metodo invocato non termina correttamente. In questo caso uno scenario come quello descritto precedentemente non sarebbe verificabile, e l'unico possibile sarebbe quello di pre-ricezione. \\Però, per necessità progettuali, legate anche alla gestione autonoma dei guasti da parte dei peer intermedi, abbiamo dovuto diversificare, tramite fork, il thread principale dell'applicazione da quello di propagazione dello stato, per non mantenere la prima invocazione del metodo remoto di aggiornamento, effettuata dal processo leader, pendente fino alla risoluzione di tutte le sotto-invocazioni sino al candidato leader. Per cui, allo stato attuale delle cose, ad ogni fork del metodo di propagazione ogni invocazione remota termina correttamente, rendendo indipendenti tra loro le invocazioni ricorsive.
\\Verificata la validità dello scenario del guasto di post-ricezione, si propone quindi di gestire tale fallimento integrando lo schema risolutivo illustrato precendentemente per il guasto pre-ricezione, con la ripetizione continua della giocata da parte del leader corrente, scandita da un timeout. Tale ripetizione viene effetuata da un thread, lanciato appositamente dal metodo \texttt{updateStatus()} a tempo di gioco, che provvede a replicare la propagazione sino a quando il token non ha effettuato il giro completo del peer. Al termine del giro il thread \emph{repeater} termina.
%\\\\
\subsubsection{Guasto del leader}\label{guastoleader}
Il guasto della tipologia leader, come anticipato nella sezioni precedenti, viene rilevato da una procedura di attesa, realizzata tramite un thread separato da quello principale, che implementa il polling verso il leader corrente. Il polling viene effettuato chiamando in maniera temporizzata il metodo remoto \texttt{areYouAlive()}, il quale, in caso di host remoto non raggiungibile, solleverà anch'esso una \texttt{RemoteException}, che verrà poi gestita opportunamente, rimuovendo il leader caduto dalla lista dei giocatori del peer che ha rilevato il guasto, e infine ricalcolando la leadership tramite il metodo \texttt{updateLeadershipStatus()}. Al termine del calcolo della leadership il \-thread\- di attesa verrà invocato sul nuovo leader corrente.
%\\\\
\subsubsection{Guasto ibrido}
Nell'ambito del guasto del leader, si presenta un caso particolare (vedi immagine \ref{fig:Diagrammaguastoibrido}), il quale si verifica a causa della simultaneità di un guasto leader e di un guasto post-ricezione.
\\A tempo di \emph{failure detection}, una volta calcolata la nuova leadership, il nuovo leader non avrà cognizione se il precedente sia riuscito o meno a lanciare la propagazione del nuovo stato di gioco, oppure se lo stato ha trovato ostacoli durante la propagazione nell'anello. L'effetto che si avrebbe è una probabile bipartizione dell'anello dovuta alla propagazione parziale di uno stato successivo a quello che il leader corrente possiede.
\\La politica di recovery utilizzata si basa sull'assunzione che, se è stato propagato uno stato, sicuramente, per le proprietà della propagazione in senso anti-gioco e per le proprietà delle RemoteCallProcedure, lo stato corrente sarà posseduto almeno dal peer che precede il leader corrente.
\\Tramite tale assunzione siamo in grado di invocare il metodo remoto\\ \texttt{forcePropagation()} su tale peer, assicurandoci che tutti i nodi che compongono l'anello abbiamo uno stato coerente condiviso.
\begin{figure}[h]
\centering
\caption{Guasto ibrido.}
\label{fig:Diagrammaguastoibrido}
\includegraphics[width=10cm]{img/guastopeeribrido.png}
\end{figure}